// 存储所有标记的id
let _ids: any[] = [];
// 存储标点对应的上一个位置
// export let markerInfo: any = {};
// 修改 markerInfo 定义
export let markerInfo: Record<string, {
  positions: [number, number];       // 当前位置
  trail: [number, number][];         // 原始航迹点（未分段）
  trailEnabled: boolean;             // 航迹线是否启用
  popup: mapboxgl.Popup | null;      // Popup 实例
  segments: {                         // 分段数据
    id: string;                      // 分段唯一标识
    points: [number, number][];      // 该段的坐标点数组
    pointCount: number;              // 该段的点数
  }[];
}> = {};

// 分段配置
export const SEGMENT_CONFIG = {
  pointsPerSegment: 200,            // 每段最大点数
  maxSegments: 100                  // 最大分段数量
};
// 动画时长
export const ANIMATION_DURATION = 1000;
// 航迹线最大点数
export const MAX_TRAIL_POINTS = 20000;
// 相机更新间隔（毫秒）
export const CAMERA_UPDATE_INTERVAL = 100;
// 是否启用追踪
let _isTrackingEnabled = false;
// 当前追踪的标记 ID
let _trackingId: string | null = null;
// 上次相机更新时间
let _lastCameraUpdateTime = 0;

// 获取所有标记的id
export const getIds = () => _ids;
// 设置所有标记的id
export const setIds = (newIds: any[]) => {
  _ids = newIds;
};
// 获取是否启用追踪
export const getIsTrackingEnabled = () => _isTrackingEnabled;
// 设置是否启用追踪
export const setIsTrackingEnabled = (value: boolean) => {
  _isTrackingEnabled = value;
};
// 获取当前追踪的标记 ID
export const getTrackingId = () => _trackingId;
// 设置当前追踪的标记 ID
export const setTrackingId = (id: string | null) => {
  _trackingId = id;
};
// 获取上次相机更新时间
export const getLastCameraUpdateTime = () => _lastCameraUpdateTime;
// 设置上次相机更新时间
export const setLastCameraUpdateTime = (time: number) => {
  _lastCameraUpdateTime = time;
};

// 线性插值函数
export const lerp = (
  start: [number, number],
  end: [number, number],
  fraction: number
): [number, number] => {
  return [
    start[0] + (end[0] - start[0]) * fraction,
    start[1] + (end[1] - start[1]) * fraction,
  ];
};

// 计算朝向的函数
export const calculateBearing = (
  start: [number, number],
  end: [number, number]
): number => {
  const startLng = (start[0] * Math.PI) / 180;
  const startLat = (start[1] * Math.PI) / 180;
  const endLng = (end[0] * Math.PI) / 180;
  const endLat = (end[1] * Math.PI) / 180;

  const y = Math.sin(endLng - startLng) * Math.cos(endLat);
  const x =
    Math.cos(startLat) * Math.sin(endLat) -
    Math.sin(startLat) * Math.cos(endLat) * Math.cos(endLng - startLng);
  const bearing = (Math.atan2(y, x) * 180) / Math.PI;
  return (bearing + 360) % 360;
};

// 计算点到线段的垂直距离（考虑线段端点，而不只是直线）
export const perpendicularDistance = (
  point: [number, number],
  lineStart: [number, number],
  lineEnd: [number, number]
): number => {
  const [x, y] = point;
  const [x1, y1] = lineStart;
  const [x2, y2] = lineEnd;

  // 线段长度的平方
  const l2 = Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2);

  // 如果线段实际上是一个点，则返回点到该点的距离
  if (l2 === 0) return Math.hypot(x - x1, y - y1);

  // 考虑线段为参数方程表示的情况下，计算投影比例t
  const t = ((x - x1) * (x2 - x1) + (y - y1) * (y2 - y1)) / l2;

  if (t < 0) {
    // 投影点在起点之前
    return Math.hypot(x - x1, y - y1);
  } else if (t > 1) {
    // 投影点在终点之后
    return Math.hypot(x - x2, y - y2);
  } else {
    // 投影点在线段上
    const projectionX = x1 + t * (x2 - x1);
    const projectionY = y1 + t * (y2 - y1);
    return Math.hypot(x - projectionX, y - projectionY);
  }
};

// 简化航迹线（Douglas-Peucker 算法）
export const simplifyTrail = (
  trail: [number, number][],
  tolerance: number = 0.0001
): [number, number][] => {
  if (trail.length <= 2) return trail;

  // 预处理：移除连续重复点
  const filteredTrail = trail.filter((point, index) => {
    if (index === 0) return true;
    const prevPoint = trail[index - 1];
    return point[0] !== prevPoint[0] || point[1] !== prevPoint[1];
  });

  const len = filteredTrail.length;
  if (len <= 2) return filteredTrail;

  // 创建标记数组，初始化为所有点都保留
  const markers = new Array(len).fill(true);
  const stack: [number, number][] = [[0, len - 1]];

  while (stack.length > 0) {
    const [startIdx, endIdx] = stack.pop()!;

    let maxDistance = 0;
    let maxIndex = 0;

    // 寻找最大距离点
    for (let i = startIdx + 1; i < endIdx; i++) {
      if (!markers[i]) continue; // 跳过已删除的点

      const distance = perpendicularDistance(
        filteredTrail[i],
        filteredTrail[startIdx],
        filteredTrail[endIdx]
      );

      if (distance > maxDistance) {
        maxDistance = distance;
        maxIndex = i;
      }
    }

    // 如果最大距离超过容差，则保留该点并继续处理
    if (maxDistance > tolerance) {
      stack.push([startIdx, maxIndex]);
      stack.push([maxIndex, endIdx]);
    } else {
      // 否则删除两点之间的所有点
      for (let i = startIdx + 1; i < endIdx; i++) {
        markers[i] = false;
      }
    }
  }

  // 根据标记数组构建结果
  return filteredTrail.filter((_, index) => markers[index]);
};

// 批量处理大轨迹，避免UI阻塞
export const simplifyTrailAsync = async (
  trail: [number, number][],
  tolerance: number = 0.0001,
  chunkSize: number = 10000,
  onProgress?: (progress: number) => void
): Promise<[number, number][]> => {
  if (trail.length <= 2) return trail;

  const totalChunks = Math.ceil(trail.length / chunkSize);
  let simplifiedChunks: [number, number][] = [];

  for (let i = 0; i < totalChunks; i++) {
    const start = i * chunkSize;
    const end = Math.min((i + 1) * chunkSize, trail.length);
    const chunk = trail.slice(start, end);

    // 如果不是第一个块，确保与前一个块有重叠，以保持连续性
    if (i > 0 && simplifiedChunks.length > 0) {
      const lastPoint = simplifiedChunks[simplifiedChunks.length - 1];
      // 找到重叠点在当前块中的索引
      const overlapIndex = chunk.findIndex(p => p[0] === lastPoint[0] && p[1] === lastPoint[1]);
      if (overlapIndex > 0) {
        // 从重叠点开始简化当前块
        const simplifiedChunk = simplifyTrail(chunk.slice(overlapIndex), tolerance);
        // 移除第一个点，避免重复
        simplifiedChunks = simplifiedChunks.concat(simplifiedChunk.slice(1));
      } else {
        simplifiedChunks = simplifiedChunks.concat(simplifyTrail(chunk, tolerance));
      }
    } else {
      simplifiedChunks = simplifiedChunks.concat(simplifyTrail(chunk, tolerance));
    }

    // 更新进度
    if (onProgress) {
      onProgress(((i + 1) / totalChunks) * 100);
    }

    // 让出线程，避免UI阻塞
    await new Promise(resolve => setTimeout(resolve, 0));
  }

  return simplifiedChunks;
};

/**
 * 更新航迹点并按点数分段
 * @param id - 标记ID
 * @param currentPoint - 当前坐标点 [lon, lat]
 */
export const updateTrailAndSegmentByPoints = (id: string, currentPoint: [number, number]) => {
  const marker = markerInfo[id];
  if (!marker) return;

  // 更新原始航迹点
  marker.trail.push(currentPoint);

  // 限制原始航迹点总数
  if (marker.trail.length > MAX_TRAIL_POINTS) {
    marker.trail.shift();
  }

  // 初始化分段（首次添加点）
  if (marker.segments.length === 0) {
    marker.segments.push({
      id: `${id}-segment-1`,
      points: [currentPoint],
      pointCount: 1
    });
    return;
  }



  // 获取当前活动分段
  const activeSegment = marker.segments[marker.segments.length - 1];

  // 添加点到当前分段
  activeSegment.points.push(currentPoint);
  activeSegment.pointCount++;

  // 检查是否达到分段阈值
  if (activeSegment.pointCount >= SEGMENT_CONFIG.pointsPerSegment) {
    // 创建新分段
    marker.segments.push({
      id: `${id}-segment-${marker.segments.length + 1}`,
      points: [currentPoint],
      pointCount: 1
    });

    // 限制分段总数
    if (marker.segments.length > SEGMENT_CONFIG.maxSegments) {
      marker.segments.shift();
    }
  }
};

/**
 * 更新航迹线显示（基于分段数据）
 */
export const updateTrailDisplay = (map: mapboxgl.Map, id: string) => {
  const marker = markerInfo[id];
  if (!marker || !marker.trailEnabled) return;

  const trailSource = map.getSource(`trail-${id}`) as mapboxgl.GeoJSONSource;
  if (!trailSource) return;

  // 将分段数据转换为 GeoJSON Features
  const features = marker.segments.map(segment => ({
    type: "Feature",
    id: segment.id,
    properties: {
      segmentId: segment.id,
      pointCount: segment.pointCount
    },
    geometry: {
      type: "LineString",
      coordinates: segment.points
    }
  }));

  // 更新数据源
  trailSource.setData({
    type: "FeatureCollection",
    features: features.filter(f => f.geometry.coordinates.length >= 2)
  });
};
// 实时飞行数据展示
export const realTimeLayer = (options: any) => {
  if (JSON.stringify(options) == "{}") {
    return;
  }
  return `<div style="
    background: #FFFFFF;
    border-radius: 6px;
    padding: 6px;
    min-width: 150px;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
    font-family: Arial, sans-serif;
  ">
    <div style="
      display: flex;
      align-items: center;
      gap: 4px;
      margin-bottom: 6px;
      padding-bottom: 4px;
      border-bottom: 1px solid #F0F0F0;
    ">
      <div style="
        background: #437EF1;
        color: white;
        padding: 1px 4px;
        border-radius: 3px;
        font-size: 10px;
      ">飞行中</div>
      <div style="
        color: #437EF1;
        font-size: 11px;
        font-weight: 500;
      ">${options.flightNumber || "B3836"}</div>
    </div>
    <div style="display: grid; grid-template-columns: 1fr 1fr; text-align: center;">
      <div>
        <div style="color: #909399; font-size: 9px;">海拔高度</div>
        <div style="color: #437EF1; font-size: 11px; font-weight: 500; font-family: DIN;">
          ${
            options.altitude || "0"
          }<span style="font-size: 9px; color: #909399; margin-left: 1px;">米</span>
        </div>
      </div>
      <div>
        <div style="color: #909399; font-size: 9px;">飞行速度</div>
        <div style="color: #437EF1; font-size: 11px; font-weight: 500; font-family: DIN;">
        </div>
      </div>
      <div>
        <div style="color: #909399; font-size: 9px;">经度</div>
        <div style="color: #437EF1; font-size: 11px; font-weight: 500; font-family: DIN;">
          ${Number(options.longitude) || "0"}
        </div>
      </div>
      <div>
        <div style="color: #909399; font-size: 9px;">纬度</div>
        <div style="color: #437EF1; font-size: 11px; font-weight: 500; font-family: DIN;">
          ${Number(options.latitude) || "0"}
        </div>
      </div>
    </div>
  </div>`;
};
